﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO.Ports;

namespace MainFrame
{
    public class TcpIP
    {
        public TcpClient Tcp;
        NetworkStream NetStream;
        public string IP;
        public int Port;
        public bool isConnected;
        #region 连接
        /// <summary>
        /// 【连接】
        /// </summary>
        /// <param name="ip"></param>
        /// <param name="port"></param>
        /// <returns></returns>
        public int Link(string ip, int port,out string Msg)
        {
            Msg = "";
            try
            {
                IP = ip;
                Port = port;
                Tcp = new TcpClient();
                if (!Tcp.Connected)
                {
                    Tcp.Connect(IPAddress.Parse(IP), Port);
                    NetStream = Tcp.GetStream();
                    NetStream.ReadTimeout = 50000;
                    NetStream.WriteTimeout = 50000;
                    if (Tcp.Connected)
                    {
                        isConnected = true;
                        Msg = "已经连接" ;
                        return 0;

                    }
                    isConnected = false;
                    Msg = "连接失败";
                    return 1;
                }
                isConnected = true;
                Msg = "连接成功";
                return 0;
            }
            catch (Exception ex)
            {
                isConnected = false;
                // displalyInfo.displayInfoMain("连接失败:" + ex.Message + ex.StackTrace);
                //MessageBox.Show("连接失败:" + ex.Message + ex.StackTrace);
                Msg= "连接失败:" + ex.Message + ex.StackTrace;
                return 1;
            }
        }
        #endregion
        #region 获取数据
        /// <summary>
        /// 【获取数据】
        /// </summary>
        /// <param name="command">命令</param>
        /// <param name="outtime">超时</param>
        /// <returns></returns>
        public int GetData(string command, out string resdata, out string Msg, short outtime = 5000, bool EnterEN = false)
        {
            Msg = "";
            resdata = "";
            int IsCheck = 1;
            try
            {
                byte[] ReadBuff = new byte[4096];
                if (!Tcp.Connected)
                {
                    Link(IP, Port,out Msg);
                }
                if (Tcp.Connected)
                {
                    if (NetStream.DataAvailable)
                    {
                        NetStream.Read(ReadBuff, 0, 4096);
                        resdata = "";
                    }
                    DateTime t1 = DateTime.Now;
                    if (EnterEN)
                        command += "\r\n";
                    NetStream.Write(Encoding.ASCII.GetBytes(command), 0, command.Length);
                    displalyInfo.displayInfoMain("发送到相机通信命令:" + command);
                    while ((DateTime.Now - t1).TotalMilliseconds < outtime)
                    {
                        if (NetStream.DataAvailable)
                        {
                            NetStream.Read(ReadBuff, 0, 4096);
                            resdata = Encoding.Default.GetString(ReadBuff).Replace("\r\n", "").Replace("\r", "").Replace("\n", "").Trim();
                            IsCheck = 0;
                            break;
                        }
                        Thread.Sleep(100);
                    }
                }
                displalyInfo.displayInfoMain("获取到相机通信命令数据:" + Encoding.Default.GetString(ReadBuff));
                ReadBuff = null;
                return IsCheck;
            }
            catch (Exception ex)
            {
                Msg = "读取数据失败:" + ex.Message;
                displalyInfo.displayInfoMain("获取相机数据失败:" + ex.Message + ex.StackTrace);
                
                return 1;
            }
        }

        /// <summary>
        /// 获取视觉返回数据
        /// </summary>
        /// <param name="resdata"></param>
        /// <param name="Msg"></param>
        /// <param name="outtime"></param>
        /// <returns></returns>
        public int GetData(out string resdata, out string Msg, short outtime = 5000)
        {
            Msg = "";
            resdata = "";
            int IsCheck = 1;
            try
            {
                byte[] ReadBuff = new byte[4096];
                if (!Tcp.Connected)
                {
                    Link(IP, Port,out Msg);
                }
                if (Tcp.Connected)
                {
                    DateTime t1 = DateTime.Now;
                    while ((DateTime.Now - t1).TotalMilliseconds < outtime)
                    {
                        if (NetStream.DataAvailable)
                        {
                            NetStream.Read(ReadBuff, 0, 4096);
                            //resdata = Encoding.Default.GetString(ReadBuff).Replace("\r\n", "").Replace("\r", "").Replace("\n", "").Trim();
                            resdata = Encoding.Default.GetString(ReadBuff).Trim();
                            IsCheck = 0;
                            break;
                        }
                        Thread.Sleep(100);
                    }
                }
                displalyInfo.displayInfoMain("获取到相机通信命令数据:" + Encoding.Default.GetString(ReadBuff));
                ReadBuff = null;
                return IsCheck;
            }
            catch (Exception ex)
            {
                Msg = "读取数据失败:" + ex.Message;
                displalyInfo.displayInfoMain("获取相机数据失败:" + ex.Message/* + ex.StackTrace*/);
                return 1;
            }
        }
        #endregion

        #region 发送数据
        /// <summary>
        /// 【发送数据】
        /// </summary>
        /// <param name="command">命令</param>
        /// <param name="outtime">超时</param>
        /// <returns></returns>
        public int SendData(string command, bool EnterEN = false)
        {
            try
            {
                byte[] ReadBuff = new byte[4096];
                if (!Tcp.Connected)
                {
                    Link(IP, Port,out string Msg);
                }
                if (Tcp.Connected)
                {
                    if (NetStream.DataAvailable)
                    {
                        NetStream.Read(ReadBuff, 0, 4096);
                    }
                    DateTime t1 = DateTime.Now;
                    if (EnterEN)
                        command += "\r\n";
                    NetStream.Write(Encoding.ASCII.GetBytes(command), 0, command.Length);
                    NetStream.Flush();// 清除缓存
                }
                displalyInfo.displayInfoMain("发送到相机命令:" + command);
                ReadBuff = null;
                return 0;
            }
            catch (Exception ex)
            {
                displalyInfo.displayInfoMain("发送到相机命令失败:" + ex.Message + ex.StackTrace);
                return 1;
            }
        }

        public int SendData2(string command, bool EnterEN = false, bool ClaerEN = false)
        {
            try
            {
                byte[] ReadBuff = new byte[4096];
                if (!Tcp.Connected)
                {
                    Link(IP, Port, out string Msg);
                }
                if (Tcp.Connected)
                {
                    if (NetStream.DataAvailable)
                    {
                        if (ClaerEN)
                            NetStream.Read(ReadBuff, 0, 4096);
                    }
                    DateTime t1 = DateTime.Now;
                    if (EnterEN)
                        command += "\r\n";
                    NetStream.Write(Encoding.ASCII.GetBytes(command), 0, command.Length);
                    NetStream.Flush();// 清除缓存
                }
                displalyInfo.displayInfoMain("发送到相机命令:" + command);
                ReadBuff = null;
                return 0;
            }
            catch (Exception ex)
            {
                displalyInfo.displayInfoMain("发送到相机命令失败:" + ex.Message + ex.StackTrace);
                return 1;
            }
        }

        #endregion

        public int Close()
        {
            try
            {
                if (NetStream != null)
                {
                    NetStream.Close();
                }
                if (Tcp != null)
                {
                    Tcp.Close();
                }
                isConnected = false;
                return 0;
            }
            catch (Exception ex)
            {
                displalyInfo.displayInfoMain("关闭连接失败:" + ex.Message + ex.StackTrace);
                return 1;
            }
        }
    }

    #region  //端口操作类
    public class port_Class
    {
        //实例一个串口
        private SerialPort SP = new SerialPort();
        private Boolean listening = false;
        private Boolean closing = false;

        //PLC状态属性
        private Boolean port_state = false;
        //获取端口缓存区字节数
        private int port_datacount = 0;
        public Boolean Port_state
        {
            get { return port_state = SP.IsOpen; }
        }

        public int Port_datacount
        {
            get { return port_datacount = SP.BytesToRead; }
            set { port_datacount = value; }
        }

        public int Port_Timeout
        {
            get;
            set;
        } = -1;

        //设置串口并打开串口
        public Boolean Open_port(string portName = "COM1", string baud = "9600", string dataBits = "8", string stopBits = "1", string parity = "None")
        {
            if (SP.IsOpen) { SP.Close(); Thread.Sleep(100); }
            SP.PortName = Convert.ToString(portName);
            SP.BaudRate = Convert.ToInt32(baud);
            SP.DataBits = Convert.ToInt32(dataBits);
            switch (stopBits)
            {
                case "1":
                    SP.StopBits = StopBits.One;
                    break;
                case "1.5":
                    SP.StopBits = StopBits.OnePointFive;
                    break;
                case "2":
                    SP.StopBits = StopBits.Two;
                    break;
            }
            switch (parity)
            {
                case "None":
                    SP.Parity = Parity.None;
                    break;
                case "Even":
                    SP.Parity = Parity.Even;
                    break;
                case "Odd":
                    SP.Parity = Parity.Odd;
                    break;
                case "Mark":
                    SP.Parity = Parity.Mark;
                    break;
                case "Space":
                    SP.Parity = Parity.Space;
                    break;
            }
            try
            {
                SP.WriteBufferSize = 4096;
                SP.ReadBufferSize = 4096;
                SP.ReadTimeout = Port_Timeout;
                SP.ReceivedBytesThreshold = 1;
                if (!SP.IsOpen) SP.Open();
                else return false;
                SP.DiscardInBuffer();
                SP.DiscardOutBuffer();
            }
            catch { return false; }
            return true;
        }

        //关闭串口
        public Boolean close_port(Boolean Dispose_state = false)
        {
            try
            {
                SP.DiscardInBuffer();
                SP.DiscardOutBuffer();
                //等待事件执行完成后才能关闭串口
                //while (listening) Application.DoEvents();   
                Thread.Sleep(200);
                SP.Close();

                if (Dispose_state)
                    SP.Dispose();
            }
            catch { return false; }

            GC.Collect();
            GC.WaitForPendingFinalizers();
            return true;
        }

        // 获取本地所有可用串口号 
        public string[] Port_Seek()
        {
            string[] portNames = SerialPort.GetPortNames();
            return portNames;
        }


        /// <summary>
        /// 清除发送接收缓存区
        /// </summary>
        /// <returns></returns>
        public Boolean portbuf_clear()
        {
            if (SP.IsOpen)
            {
                SP.DiscardOutBuffer();
                SP.DiscardInBuffer();
                return true;
            }
            else
            { return false; }
        }

        /// <summary>
        /// //写字符
        /// </summary>
        /// <param name="str">要写入的字符</param>
        /// <returns>True成功，则失败</returns>
        public Boolean Writeport_string(String str)
        {
            char[] SendBuffer = new char[4096];
            try
            {
                if (SP.IsOpen)
                {
                    SP.DiscardOutBuffer();
                    SendBuffer = str.ToCharArray();
                    SP.Write(SendBuffer, 0, SendBuffer.Length);
                }
                else { return false; }
            }
            catch { return false; }
            return true;
        }

        /// <summary>
        /// //写字节
        /// </summary>
        /// <param name="str">要写入的字节</param>
        /// <returns>True成功，则失败</returns>
        public Boolean Writeport_byte(byte[] str)
        {
            try
            {
                if (SP.IsOpen)
                {
                    SP.DiscardOutBuffer();
                    SP.Write(str, 0, str.Length);
                }
                else { return false; }
            }
            catch { return false; }
            return true;
        }

        /// <summary>
        /// //读字符
        /// </summary>
        /// <returns>返回串口数据</returns>
        public string Readport_string()
        {
            string dastring = "";
            char[] ReadBuffer = null;

            try
            {
                if (SP.IsOpen)
                {
                    ReadBuffer = new char[SP.BytesToRead];
                    SP.Read(ReadBuffer, 0, SP.BytesToRead);
                    string instring = new string(ReadBuffer);
                    dastring += instring;
                    SP.DiscardInBuffer();
                }
            }
            catch { return ""; }
            return dastring;
        }

        /// <summary>
        /// //读字节
        /// </summary>
        /// <returns>返回串口数据</returns>
        public byte[] Readport_byte()
        {
            byte[] ReadBuffer_byte;

            try
            {
                if (SP.IsOpen)
                {
                    ReadBuffer_byte = new byte[SP.BytesToRead];
                    SP.Read(ReadBuffer_byte, 0, SP.BytesToRead);
                    SP.DiscardInBuffer();
                    return ReadBuffer_byte;
                }
            }
            catch {; }
            return (new byte[0]);
        }

        public string _Readport_string()
        {
            string dastring = "";
            //char[] ReadBuffer = new char[SP.BytesToRead];

            try
            {
                if (SP.IsOpen)
                {
                    dastring = SP.ReadTo("\r");
                    SP.DiscardInBuffer();
                }
            }
            catch { return ""; }
            return dastring;
        }

        public string _Readport_string(string value)
        {
            string dastring = "";

            try
            {
                if (SP.IsOpen)
                {
                    dastring = SP.ReadTo("value");
                    SP.DiscardInBuffer();
                }
            }
            catch { return ""; }
            return dastring;
        }


    }
    #endregion
}
